package Similarity;

import parser.DataParser;

public class SimilarityAlgorithm {

	private static final double THRESHOLD = 0.5;
	
	static double[][] data = {	{0.75, 0.88, 1.00, 1.15, 1.40, 0},		//Required software reliability
		{0   , 0.94, 1.00, 1.08, 1.16, 0},		//Data base size
		{0.70, 0.85, 1.00, 1.15, 1.30, 1.65},	//Process complexity
		{0   , 0   , 1.00, 1.11, 1.30, 1.66},	//Time constraint for CPU
		{0   , 0   , 1.00, 1.06, 1.21, 1.56},	//Main memory constraint
		{0   , 0.87, 1.00, 1.15, 1.30, 0},		//Machine volatility
		{0   , 0.87, 1.00, 1.07, 1.15, 0},		//Turnaround time 
		{1.46, 1.19, 1.00, 0.86, 0.71, 0},		//Analysts capability
		{1.29, 1.13, 1.00, 0.91, 0.82, 0},		//Application experience
		{1.42, 1.17, 1.00, 0.86, 0.70, 0},		//Programmers capability
		{1.21, 1.10, 1.00, 0.90, 0   , 0},		//Virtual machine experience
		{1.14, 1.07, 1.00, 0.95, 0   , 0},		//Language experience
		{1.24, 1.10, 1.00, 0.91, 0.82, 0},		//Modern programming practices
		{1.24, 1.10, 1.00, 0.91, 0.83, 0},		//Use of software tools
		{1.23, 1.08, 1.00, 1.04, 1.10, 0} }; 	//Schedule constraint
	
	public static void main(String[] args) {
		
		double[][] result;
		DataParser dp = new DataParser("data.txt");
		EffortEstimator ee = new EffortEstimator(10.4); //Kilo Lines of Code
		String testString = "Nominal,Low,High,Nominal,Nominal,Low,Low,Nominal,Nominal,Nominal,Nominal,High,High,Nominal,Low";
		
		String[] s = testString.split(",");
		
		int[] k = new int[15];
		int[] l = new int[15];
		double[] pNew 		= new double[15];
		double[] pExisting 	= new double[15];
		double[] min 		= dp.getMin();
		double[] max		= dp.getMax();	
		try {
			result = dp.parse();
			for(int i = 0; i < 60; i++) {
				for(int j = 0; j < 15; j++) {
					k[j] = mapLevelToColumn(s[j]);
					int a = k[j];
					pNew[j] 		= data[j][a];
					pExisting[j]	= result[i][j];
				}
				double similarity = calculateSimilarity(pNew, pExisting, min, max);
				System.out.println(similarity);
				if(similarity >= THRESHOLD) {
					Case c = new Case(similarity, result[i][15], result[i][16]);
					ee.addCase(c);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.print(ee.calculate());
		
	}
	
	
	
	/**
	 * Map a string to an index number.
	 * 
	 * @param s
	 * @return
	 */
	public static int mapLevelToColumn(String s){
		if (s.equals("Very_Low")){
			return 0;
		} else if (s.equals("Low")){
			return 1;
		} else if (s.equals("Nominal")){
			return 2;
		} else if (s.equals("High")){
			return 3;
		} else if (s.equals("Very_High")){
			return 4;
		} else if (s.equals("Extra_High")){
			return 5;
		} else {
			return -1;
		}
	}
	/**
	 * Calculate the similarity between a generated double array and a data set entry. 
	 * 
	 * @param pNew		The double vector you generate from the GUI
	 * @param pExisting	An existing double vector from a given data set
	 * @param min		The minimum value for each column from the data set
	 * @param max		The maximum value for each column from the data set 
	 * @return 			Returns a value between 0.0 and 1.0 		
	 */
	private static double calculateSimilarity(double[] pNew, double[] pExisting, double[] min, double[] max){
		double delta = 0;
		
		for (int i = 0; i<pNew.length; i++){
			delta += Math.pow(Math.abs(pNew[i] - pExisting[i])/(max[i]-min[i]),2);
		}
		
		double distance = Math.sqrt(delta/pNew.length);
		
		return 1-distance;
	}

}
